//
//  RunnerSetup.swift
//  IOSTestRunnerTests
//
//  Created by liao xiangsen on 2019/8/24.
//  Copyright © 2019年 liao xiangsen. All rights reserved.
//

import os.log

class RunnerSetup {
    public static let RUNNER_CONFIG_ENV = "runner_config"
    enum RunnerSetupError: Error {
        case InvalidConfigInfo(String)
        case SDKSetupError(String)
    }
    
    private static var _sharedInstance: RunnerSetup!
    public static var sharedInstance: RunnerSetup! {
        if _sharedInstance == nil {
            do {
                let instance = try RunnerSetup()
                _sharedInstance = instance
            } catch {
                Utils.log(tag: "RunnerSetup", str: error.localizedDescription)
                return nil
            }
        }
        return _sharedInstance
    }
    
    public let runnerConfig: StockTesting_RunnerConfig
    public let resultCollector: TestResultCollector
    
    private init() throws {
        var infoDict: [String: Any]
        if Bundle.main.infoDictionary == nil {
            throw RunnerSetupError.InvalidConfigInfo("infoDictionary is nil")
        } else {
            infoDict = Bundle.main.infoDictionary!
            if infoDict[RunnerSetup.RUNNER_CONFIG_ENV] == nil
                || !(infoDict[RunnerSetup.RUNNER_CONFIG_ENV] is String) {
                throw RunnerSetupError.InvalidConfigInfo("runner_config value is nil or invalid")
            }
        }
        let cfgStr = infoDict[RunnerSetup.RUNNER_CONFIG_ENV]! as! String
//        let cfgStr = "CgRUSi0xEipSVU4tQS0wYjI0ZDc4OS1kYWUyLTRhMzQtODAxYi02OGMxNjI0ZTc5NWEanAUKLEo2SVBsazVBRVUrMi9ZaTU5cmZZbnNGUXRkdE9nQW85R0F6eXN4OGNpT009EixWVlcwRm5vN0JFWnQxYS95NktMTTM2dWo5cWNqdzdDQUhEd1daS0RsV0RzPRolCgRoa2F6Eh0KG2h0dHA6Ly8xMTQuODAuMTU1LjEzMzoyMjAxNholCgVzaHN6dhIcChpodHRwOi8vMTE0LjgwLjE1NS42MToyMjAxNholCgRoa2QxEh0KG2h0dHA6Ly8xMTQuODAuMTU1LjEzMzoyMjAxNholCgRoazEwEh0KG2h0dHA6Ly8xMTQuODAuMTU1LjEzMzoyMjAxNhoiCgJzaBIcChpodHRwOi8vMTE0LjgwLjE1NS42MToyMjAxNholCgRoa2R6Eh0KG2h0dHA6Ly8xMTQuODAuMTU1LjEzMzoyMjAxNhoiCgJnZhIcChpodHRwOi8vMTE0LjgwLjE1NS42MToyMjAxMxoiCgJuZhIcChpodHRwOi8vMTE0LjgwLjE1NS41ODoyMjAxMxokCgNoazESHQobaHR0cDovLzExNC44MC4xNTUuMTMzOjIyMDE2GiUKBGhrYTESHQobaHR0cDovLzExNC44MC4xNTUuMTMzOjIyMDE2GiIKAnBiEhwKGmh0dHA6Ly8xMTQuODAuMTU1LjYxOjIyMDE2GiIKAmJqEhwKGmh0dHA6Ly8xMTQuODAuMTU1LjYxOjIyMDE2GiQKA2hrNRIdChtodHRwOi8vMTE0LjgwLjE1NS4xMzM6MjIwMTYaIgoCY2YSHAoaaHR0cDovLzExNC44MC4xNTUuNjE6MjIwMTYaIgoCc3oSHAoaaHR0cDovLzExNC44MC4xNTUuNjE6MjIwMTYiDEoEaGsxMEoEaGthMSKwKwoOT0hMQ1YyVGVzdENhc2UYAyJleyJDT0RFIjogIjQzMDAwNS5iaiIsICJTVUJUWVBFIjogIjEwMDUiLCAiUEVSSU9EIjogIjAiLCAiUkVRVUVTVFRZUEUiOiAiMCIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIn0iZXsiQ09ERSI6ICI4OTkwMDEuYmoiLCAiU1VCVFlQRSI6ICIxNDAwIiwgIlBFUklPRCI6ICI4IiwgIlJFUVVFU1RUWVBFIjogIjAiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCJ9ImV7IkNPREUiOiAiODM5ODA2LmJqIiwgIlNVQlRZUEUiOiAiMTAwNSIsICJQRVJJT0QiOiAiMCIsICJSRVFVRVNUVFlQRSI6ICIwIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjEifSJleyJDT0RFIjogIjg5OTAwMS5iaiIsICJTVUJUWVBFIjogIjE0MDAiLCAiUEVSSU9EIjogIjAiLCAiUkVRVUVTVFRZUEUiOiAiMCIsICJQUklDRUFESlVTVEVETU9ERSI6ICIxIn0if3siQ09ERSI6ICI4Mzk4MDYuYmoiLCAiU1VCVFlQRSI6ICIxMDA1IiwgIlBFUklPRCI6ICI4IiwgIkRBVEUiOiAiMjAxOTEwMzExNTAwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIxIn0if3siQ09ERSI6ICI4OTkwMDEuYmoiLCAiU1VCVFlQRSI6ICIxNDAwIiwgIlBFUklPRCI6ICI4IiwgIkRBVEUiOiAiMjAxOTEwMDEwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIxIn0if3siQ09ERSI6ICI0MzAwMDUuYmoiLCAiU1VCVFlQRSI6ICIxMDA1IiwgIlBFUklPRCI6ICI4IiwgIkRBVEUiOiAiMjAxOTEwMjgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMiIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIn0if3siQ09ERSI6ICI4OTkwMDEuYmoiLCAiU1VCVFlQRSI6ICIxNDAwIiwgIlBFUklPRCI6ICI4IiwgIkRBVEUiOiAiMjAxOTEwMjgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMiIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIn0idHsiQ09ERSI6ICI4Mzk4MDYuYmoiLCAiU1VCVFlQRSI6ICIxMDA1IiwgIlBFUklPRCI6ICI4IiwgIlJFUVVFU1RUWVBFIjogIjAiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMSIsICJDT1VOVCI6ICIyMCJ9InR7IkNPREUiOiAiODk5MDAxLmJqIiwgIlNVQlRZUEUiOiAiMTQwMCIsICJQRVJJT0QiOiAiOCIsICJSRVFVRVNUVFlQRSI6ICIwIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjEiLCAiQ09VTlQiOiAiMjAifSKOAXsiQ09ERSI6ICI4Mzk4MDYuYmoiLCAiU1VCVFlQRSI6ICIxMDA1IiwgIlBFUklPRCI6ICI4IiwgIkRBVEUiOiAiMjAxOTExMTgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIiwgIkNPVU5UIjogIjIwIn0ijgF7IkNPREUiOiAiODM5ODA2LmJqIiwgIlNVQlRZUEUiOiAiMTAwNSIsICJQRVJJT0QiOiAiMyIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9Io4BeyJDT0RFIjogIjQzMDAwNS5iaiIsICJTVUJUWVBFIjogIjEwMDUiLCAiUEVSSU9EIjogIjQiLCAiREFURSI6ICIyMDE5MTExODA5MzAwMCIsICJSRVFVRVNUVFlQRSI6ICIxIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjAiLCAiQ09VTlQiOiAiMjAifSKOAXsiQ09ERSI6ICI4Mzk4MDYuYmoiLCAiU1VCVFlQRSI6ICIxMDA1IiwgIlBFUklPRCI6ICI1IiwgIkRBVEUiOiAiMjAxOTExMTgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIiwgIkNPVU5UIjogIjIwIn0ijgF7IkNPREUiOiAiNDMwMDA1LmJqIiwgIlNVQlRZUEUiOiAiMTAwNSIsICJQRVJJT0QiOiAiNiIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9Io4BeyJDT0RFIjogIjQzMDAwNS5iaiIsICJTVUJUWVBFIjogIjEwMDUiLCAiUEVSSU9EIjogIjciLCAiREFURSI6ICIyMDE5MTExODA5MzAwMCIsICJSRVFVRVNUVFlQRSI6ICIxIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjAiLCAiQ09VTlQiOiAiMjAifSKOAXsiQ09ERSI6ICI0MzAwMDUuYmoiLCAiU1VCVFlQRSI6ICIxMDA1IiwgIlBFUklPRCI6ICIwIiwgIkRBVEUiOiAiMjAxOTExMTgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIiwgIkNPVU5UIjogIjIwIn0ijgF7IkNPREUiOiAiODM5ODA2LmJqIiwgIlNVQlRZUEUiOiAiMTAwNSIsICJQRVJJT0QiOiAiMSIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9Io4BeyJDT0RFIjogIjgzOTgwNi5iaiIsICJTVUJUWVBFIjogIjEwMDUiLCAiUEVSSU9EIjogIjIiLCAiREFURSI6ICIyMDE5MTExODA5MzAwMCIsICJSRVFVRVNUVFlQRSI6ICIxIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjAiLCAiQ09VTlQiOiAiMjAifSKOAXsiQ09ERSI6ICI4Mzk4MDYuYmoiLCAiU1VCVFlQRSI6ICIxMDA1IiwgIlBFUklPRCI6ICI5IiwgIkRBVEUiOiAiMjAxOTExMTgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIiwgIkNPVU5UIjogIjIwIn0ijgF7IkNPREUiOiAiODk5MDAxLmJqIiwgIlNVQlRZUEUiOiAiMTQwMCIsICJQRVJJT0QiOiAiOCIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9Io4BeyJDT0RFIjogIjg5OTAwMS5iaiIsICJTVUJUWVBFIjogIjE0MDAiLCAiUEVSSU9EIjogIjMiLCAiREFURSI6ICIyMDE5MTExODA5MzAwMCIsICJSRVFVRVNUVFlQRSI6ICIxIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjAiLCAiQ09VTlQiOiAiMjAifSKOAXsiQ09ERSI6ICI4OTkwMDEuYmoiLCAiU1VCVFlQRSI6ICIxNDAwIiwgIlBFUklPRCI6ICI0IiwgIkRBVEUiOiAiMjAxOTExMTgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIiwgIkNPVU5UIjogIjIwIn0ijgF7IkNPREUiOiAiODk5MDAxLmJqIiwgIlNVQlRZUEUiOiAiMTQwMCIsICJQRVJJT0QiOiAiNSIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9Io4BeyJDT0RFIjogIjg5OTAwMS5iaiIsICJTVUJUWVBFIjogIjE0MDAiLCAiUEVSSU9EIjogIjYiLCAiREFURSI6ICIyMDE5MTExODA5MzAwMCIsICJSRVFVRVNUVFlQRSI6ICIxIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjAiLCAiQ09VTlQiOiAiMjAifSKOAXsiQ09ERSI6ICI4OTkwMDEuYmoiLCAiU1VCVFlQRSI6ICIxNDAwIiwgIlBFUklPRCI6ICI3IiwgIkRBVEUiOiAiMjAxOTExMTgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIiwgIkNPVU5UIjogIjIwIn0ijgF7IkNPREUiOiAiODk5MDAxLmJqIiwgIlNVQlRZUEUiOiAiMTQwMCIsICJQRVJJT0QiOiAiMCIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9Io4BeyJDT0RFIjogIjg5OTAwMS5iaiIsICJTVUJUWVBFIjogIjE0MDAiLCAiUEVSSU9EIjogIjEiLCAiREFURSI6ICIyMDE5MTExODA5MzAwMCIsICJSRVFVRVNUVFlQRSI6ICIxIiwgIlBSSUNFQURKVVNURURNT0RFIjogIjAiLCAiQ09VTlQiOiAiMjAifSKOAXsiQ09ERSI6ICI4OTkwMDEuYmoiLCAiU1VCVFlQRSI6ICIxNDAwIiwgIlBFUklPRCI6ICIyIiwgIkRBVEUiOiAiMjAxOTExMTgwOTMwMDAiLCAiUkVRVUVTVFRZUEUiOiAiMSIsICJQUklDRUFESlVTVEVETU9ERSI6ICIwIiwgIkNPVU5UIjogIjIwIn0ijgF7IkNPREUiOiAiODk5MDAxLmJqIiwgIlNVQlRZUEUiOiAiMTQwMCIsICJQRVJJT0QiOiAiOSIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiOCIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiMyIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiNCIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiNSIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiNiIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiNyIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiMCIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiMSIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiMiIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9IpABeyJDT0RFIjogIjg0MTAwMy5iaiIsICJTVUJUWVBFIjogIjEwMTMwMiIsICJQRVJJT0QiOiAiOSIsICJEQVRFIjogIjIwMTkxMTE4MDkzMDAwIiwgIlJFUVVFU1RUWVBFIjogIjEiLCAiUFJJQ0VBREpVU1RFRE1PREUiOiAiMCIsICJDT1VOVCI6ICIyMCJ9InUKD09wdGlvblRUZXN0Q2FzZRgDIi97IlNUT0NLSUQiOiAiMTU5OTE1LnN6IiwgIkVYUElSRU1PTlRIIjogIjE5MTEifSIveyJTVE9DS0lEIjogIjUxMDA1MC5zaCIsICJFWFBJUkVNT05USCI6ICIxOTExIn0="
        do {
            runnerConfig = try StockTesting_RunnerConfig(serializedData: Data(base64Encoded: cfgStr)!)
        } catch {
            Utils.log(tag: "RunnerSetup", str: "Protobuf deserialize error: \(error)")
            throw RunnerSetupError.InvalidConfigInfo(error.localizedDescription)
        }
        Utils.log(tag: "RunnerSetup", str: "\(runnerConfig)")
        do {
            try SDKSetup.setup(sdkConfig: runnerConfig.sdkConfig)
        } catch {
            Utils.log(tag: "RunnerSetup", str: "SDK setup error: \(error)")
            throw RunnerSetupError.SDKSetupError(error.localizedDescription)
        }
        // Setup has done
        self.resultCollector = TestResultLogCollector(jobID: runnerConfig.jobID, runnerID: runnerConfig.runnerID)
        XCTestObservationCenter.shared.addTestObserver(StockTestObservation(collector: self.resultCollector))
    }
    
    public func getTestcaseNames() -> [StockTestCaseName] {
        var names = [StockTestCaseName]()
        for item in runnerConfig.casesConfig {
            if let name = StockTestCaseName.fromString(item.testcaseID) {
                names.append(name)
            }
        }
        Utils.log(tag: "names", str: "\(names)")
        return names
    }
    
    public func getTestCaseConfigDict() -> [StockTestCaseName: StockTesting_TestcaseConfig] {
        var cfgDict = [StockTestCaseName: StockTesting_TestcaseConfig]()
        for caseCfg in runnerConfig.casesConfig {
            if let name = StockTestCaseName.fromString(caseCfg.testcaseID) {
                cfgDict[name] = caseCfg
            }
        }
        return cfgDict
    }
}
